package main

import "fmt"

func main() {
	// Go语言类型断言
	var count interface{}
	count = 42
	value, ok := count.(int)
	fmt.Println(value+1, ",", ok)

	var some interface{}
	// 不接收第二个参数也就是上面代码中的 ok，断言失败时会直接造成一个 panic
	// value1:= some.(int)
	// 隐式处理不会panic
	value1, _ := some.(int)
	fmt.Println(value1)

	// 断言结合if语句
	if str, ok := count.(string); ok {
		fmt.Println(str)
	} else {
		fmt.Println("类型断言失败")
	}
	// 类型开关
	getType(100)
	getType("hello")
	getType(3.14)
	getType([]int{1, 2, 3})
}

// switch 实现类型分支时，case 后面跟的是类型而不是值
func getType(a interface{}) {
	switch a.(type) {
	case int:
		fmt.Println("the type of a is int")
	case string:
		fmt.Println("the type of a is string")
	case float64:
		fmt.Println("the type of a is float")
	default:
		fmt.Println("unknown type")
	}
}

// Go 断言是“拆盒子”，拆错就炸；TS 的 is 是“贴标签”，贴错顶多不进门。
// Go	运行时	失败直接 panic（或 ,ok 返回 false）
// TS	编译期	窄化失败→类型不变，不会抛异常
